package com.haohan.cloud.scm.goods.core.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haohan.cloud.scm.api.common.constant.IGoodsConstant;
import com.haohan.cloud.scm.api.constant.ScmCacheNameConstant;
import com.haohan.cloud.scm.api.constant.enums.goods.ModelAttrNameEnum;
import com.haohan.cloud.scm.api.constant.enums.manage.PhotoTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.opc.YesNoEnum;
import com.haohan.cloud.scm.api.goods.dto.*;
import com.haohan.cloud.scm.api.goods.entity.*;
import com.haohan.cloud.scm.api.goods.req.manage.EditGoodsReq;
import com.haohan.cloud.scm.api.goods.req.manage.EditModelReq;
import com.haohan.cloud.scm.api.goods.req.manage.GoodsListReq;
import com.haohan.cloud.scm.api.goods.req.manage.GoodsPricingReq;
import com.haohan.cloud.scm.api.goods.trans.GoodsTrans;
import com.haohan.cloud.scm.api.goods.vo.GoodsModelVO;
import com.haohan.cloud.scm.api.goods.vo.GoodsVO;
import com.haohan.cloud.scm.api.manage.dto.PhotoGroupDTO;
import com.haohan.cloud.scm.api.manage.trans.PhotoTrans;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.goods.service.*;
import com.haohan.cloud.scm.goods.utils.ScmGoodsUtils;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author dy
 * @date 2020/6/6
 */
@Service
@AllArgsConstructor
public class GoodsCoreBaseService {

    private final GoodsCollectionsService goodsCollectionsService;
    private final PlatformGoodsPriceService platformGoodsPriceService;
    private final GoodsService goodsService;
    private final GoodsModelService goodsModelService;
    private final GoodsModelTotalService goodsModelTotalService;
    private final GoodsCategoryService goodsCategoryService;
    private final GoodsPriceRuleService goodsPriceRuleService;
    private final ScmGoodsUtils scmGoodsUtils;


    /**
     * 查询商品列表
     *
     * @param page
     * @param req  goodsSn、goodsStatus、goodsType、salecFlag、categoryId、goodsName、scanCode
     * @return
     */
    @Cacheable(value = ScmCacheNameConstant.GOODS_INFO_DETAIL, key = "'fetchPage' + #page.current +'.'+ #page.size + #req")
    public IPage<Goods> fetchPage(Page<Goods> page, GoodsListReq req) {
        Goods goods = req.transTo();
        // 分类及子分类
        Set<String> categoryIdSet = StrUtil.isNotEmpty(goods.getGoodsCategoryId()) ? goodsCategoryService.fetchChildren(goods.getGoodsCategoryId()) : new HashSet<>(16);
        goods.setGoodsCategoryId(null);
        // 分类id集合
        if (CollUtil.isNotEmpty(req.getCategoryIds())) {
            categoryIdSet.addAll(req.getCategoryIds());
        }
        String goodsName = goods.getGoodsName();
        boolean nameFlag = StrUtil.isNotEmpty(goodsName);
        goods.setGoodsName(null);
        goods.setSimpleDesc(null);
        QueryWrapper<Goods> query = Wrappers.query(goods);
        query.lambda()
                .in(CollUtil.isNotEmpty(req.getGoodsIds()), Goods::getId, req.getGoodsIds())
                // 分类及子分类
                .in(!categoryIdSet.isEmpty(), Goods::getGoodsCategoryId, categoryIdSet)
                // 商品名称 或别名 模糊查询
                .and(nameFlag, q -> q.like(Goods::getGoodsName, goodsName)
                        .or().like(Goods::getSimpleDesc, goodsName));
        query.orderByAsc("sort+0");
        return goodsService.page(page, query);
    }

    /**
     * 查询商品详情
     * 放入缓存
     *
     * @param goods      已有属性实例
     * @param pricingReq pricingDate、  pricingMerchantId或buyerId
     * @return
     */
    @Cacheable(value = ScmCacheNameConstant.GOODS_INFO_DETAIL, key = "#goods.id+':'+#pricingReq.pricingMerchantId+#pricingReq.pricingDate+#pricingReq.buyerId")
    public GoodsVO fetchGoodsInfo(Goods goods, GoodsPricingReq pricingReq) {
        GoodsVO result = new GoodsVO(goods);
        String goodsId = goods.getId();
        GoodsCategory category = goodsCategoryService.getById(goods.getGoodsCategoryId());
        if (null != category) {
            result.setCategoryName(category.getName());
        }
        // 价格
        GoodsPriceRule priceRule = checkedPriceRule(goodsId);
        GoodsTrans.priceRuleHandle(priceRule);
        result.copyPrice(priceRule);
        // 规格名
        List<GoodsModelTotal> modelTotalList = checkedGoodsModelTotal(goodsId);
        // 规格名称：规格类型名称
        Map<String, String> map = modelTotalList.stream().collect(Collectors.toMap(GoodsModelTotal::getSubModelName, GoodsModelTotal::getModelName, (k1, k2) -> k1));
        // 转换规格属性名放入map
        result.setAttrMap(GoodsTrans.fetchAttrMap(modelTotalList));
        // todo salec优化后删除
        result.setModelTotalList(modelTotalList);
        // 规格
        List<GoodsModel> modelList = checkedGoodsModel(goodsId);
        // 联查平台商品定价
        pricingReq.setShopId(result.getShopId());
        pricingReq.setGoodsId(goodsId);
        Map<String, PlatformGoodsPrice> priceMap = fetchPlatformPriceByGoods(pricingReq);
        result.setModelList(modelList.stream()
                .map(item -> {
                    GoodsModelVO modelVO = GoodsTrans.transToVO(item, map, goods.getGoodsName());
                    GoodsTrans.modelPlatformPrice(priceMap.get(modelVO.getModelId()), modelVO);
                    return modelVO;
                })
                .collect(Collectors.toList()));
        // 图片组
        result.setPhotoList(PhotoTrans.photoListTrans(scmGoodsUtils.fetchPhotoList(goods.getPhotoGroupNum())));
        return result;
    }

    /**
     * 获取商品所有规格的平台定价
     * 同一时间段内 一个商家下 商品规格只有一个定价
     * key: goodsModelId
     *
     * @param pricingReq goodsId、shopId、pricingDate、  pricingMerchantId或buyerId
     * @return
     */
    private Map<String, PlatformGoodsPrice> fetchPlatformPriceByGoods(GoodsPricingReq pricingReq) {
        PlatformPriceSqlDTO query = new PlatformPriceSqlDTO();
        // 定价平台商家id
        query.setPricingPmId(scmGoodsUtils.fetchPricingPmId(pricingReq.getShopId()));
        // 使用定价商家id
        query.setMerchantId(scmGoodsUtils.fetchPricingMerchantId(pricingReq.getPricingMerchantId(), pricingReq.getBuyerId()));
        query.setQueryDate(null == pricingReq.getPricingDate() ? LocalDate.now() : pricingReq.getPricingDate());
        query.setGoodsId(pricingReq.getGoodsId());
        List<PlatformGoodsPrice> list = platformGoodsPriceService.fetchListByDate(query);
        if (list.isEmpty()) {
            return new HashMap<>(4);
        }
        // 同一时间段内 一个商家下 商品规格只有一个定价
        return list.stream().collect(Collectors.toMap(PlatformGoodsPrice::getModelId, Function.identity(), (old, value) -> old));
    }

    /**
     * 新增商品及规格属性 (商品导入和创建平台商品使用)
     *
     * @param goodsDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public GoodsDTO saveGoodsWithDetail(GoodsDTO goodsDTO) {
        // 保存商品
        Goods goods = goodsDTO.transToGoods();
        // 多规格 状态
        if (goodsDTO.getModelList().size() > 1) {
            goods.setGoodsModel(YesNoEnum.yes);
        }
        goods.setId(null);
        goods.setGoodsSn(null);
        goodsService.save(goods);
        String goodsId = goods.getId();
        String goodsSn = goods.getGoodsSn();
        // 回传
        goodsDTO.setId(goodsId);
        goodsDTO.setGoodsSn(goodsSn);
        // 保存定价规则
        GoodsPriceRule goodsPriceRule = goodsDTO.transToPriceRule();
        goodsPriceRule.setGoodsId(goodsId);
        GoodsTrans.priceRuleHandle(goodsPriceRule);
        goodsPriceRuleService.save(goodsPriceRule);
        // key: 规格类型值
        Map<String, String> modelCodeMap = new HashMap<>(goodsDTO.getModelList().size() * 2);
        // 保存规格名称
        Integer codeNum = 30;
        for (Map.Entry<ModelAttrNameEnum, List<String>> entry : goodsDTO.getAttrMap().entrySet()) {
            for (String modelValue : entry.getValue()) {
                GoodsModelTotal modelTotal = new GoodsModelTotal();
                modelTotal.setGoodsId(goodsId);
                modelTotal.setModelName(entry.getKey().getDesc());
                modelTotal.setModelId(entry.getKey().getType());
                modelTotal.setSubModelId(String.valueOf(codeNum));
                modelTotal.setSubModelName(modelValue);
                codeNum++;
                goodsModelTotalService.save(modelTotal);
                // 正常是无重名的规格类型值的
                if (modelCodeMap.containsKey(modelValue)) {
                    modelValue = modelValue + modelValue;
                }
                modelCodeMap.put(modelValue, modelTotal.getSubModelId());
            }
        }
        // 保存规格
        int num = 1;
        for (GoodsModelDTO model : goodsDTO.getModelList()) {
            model.setGoodsId(goodsId);
            GoodsModel goodsModel = model.transTo();
            goodsModel.setGoodsModelSn(GoodsTrans.genGoodsModelSn(goodsSn, num));
            // 规格组合code处理
            List<String> codeList = new ArrayList<>(8);
            String[] modelNameArray = StrUtil.split(model.getModelName(), StrUtil.COMMA);
            for (String name : modelNameArray) {
                String code = modelCodeMap.get(name);
                if (null == code) {
                    code = modelCodeMap.get(name + name);
                }
                if (null != code) {
                    codeList.add(code);
                }
            }
            goodsModel.setModel(CollUtil.join(codeList, StrUtil.COMMA));
            goodsModel.setId(null);
            goodsModelService.save(goodsModel);
            // 回传
            model.setId(goodsModel.getId());
            model.setGoodsModelSn(goodsModel.getGoodsModelSn());
            num++;
        }
        return goodsDTO;
    }

    /**
     * 新增商品 规格处理及保存
     *
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Goods addGoods(EditGoodsReq req) {
        Goods goods = req.transTo();
        // 商品规格  规格处理验证
        goods.setGoodsSn("");
        EditGoodsModelDTO result = editGoodsModel(req.getModelList(), new ArrayList<>(4), new ArrayList<>(4), goods);
        // 状态默认
        GoodsTrans.goodsInitDefault(goods);
        // 图片组
        savePhotoGroup(goods, req.getPhotoList());
        goodsService.save(goods);
        // 价格
        GoodsPriceRule priceRule = GoodsTrans.initGoodsPriceRule(goods, req);
        goodsPriceRuleService.save(priceRule);
        // 保存列表
        result.getUseModelList().forEach(model -> {
            model.setGoodsId(goods.getId());
            // 规格编号设置: 商品编号+M+后缀数字
            model.setGoodsModelSn(goods.getGoodsSn().concat(model.getGoodsModelSn()));
            goodsModelService.save(model);
        });
        result.getUseTotalList().forEach(total -> {
            total.setGoodsId(goods.getId());
            goodsModelTotalService.save(total);
        });
        return goods;
    }

    /**
     * 修改商品 规格处理及保存
     *
     * @param req
     * @param existGoods
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Goods modifyGoods(EditGoodsReq req, Goods existGoods) {
        Goods goods = req.transTo();
        goods.setGoodsSn(existGoods.getGoodsSn());
        GoodsPriceRule existPriceRule = checkedPriceRule(goods.getId());
        // 商品规格 规格处理验证
        List<GoodsModel> existModelList = checkedGoodsModel(goods.getId());
        List<GoodsModelTotal> existTotalList = checkedGoodsModelTotal(goods.getId());
        EditGoodsModelDTO editResult = editGoodsModel(req.getModelList(), existModelList, existTotalList, goods);
        // 图片组
        goods.setPhotoGroupNum(existGoods.getPhotoGroupNum());
        savePhotoGroup(goods, req.getPhotoList());
        goodsService.updateById(goods);
        // 价格
        GoodsPriceRule updatePriceRule = GoodsTrans.initGoodsPriceRule(goods, req);
        updatePriceRule.setId(existPriceRule.getId());
        goodsPriceRuleService.updateById(updatePriceRule);
        // 保存列表
        editResult.getUseModelList().forEach(model -> {
            if (StrUtil.isEmpty(model.getId())) {
                goodsModelService.save(model);
            } else {
                goodsModelService.updateById(model);
            }
        });
        editResult.getUseTotalList().forEach(total -> {
            if (StrUtil.isEmpty(total.getId())) {
                goodsModelTotalService.save(total);
            } else {
                goodsModelTotalService.updateById(total);
            }
        });
        editResult.getDeleteModelList().forEach(model -> goodsModelService.removeById(model.getId()));
        editResult.getDeleteTotalList().forEach(total -> goodsModelTotalService.removeById(total.getId()));
        return goods;
    }

    /**
     * 图片组保存
     *
     * @param goods
     * @param photoList
     */
    private void savePhotoGroup(Goods goods, List<String> photoList) {
        if (null != photoList) {
            PhotoGroupDTO photoGroupDTO = PhotoTrans.initToEdit(goods.getGoodsName().concat("图片"), goods.getPhotoGroupNum(), PhotoTypeEnum.productPhotos, photoList);
            goods.setPhotoGroupNum(scmGoodsUtils.savePhotoGroup(photoGroupDTO));
        }
    }

    /**
     * 商品规格新增、修改
     *
     * @param editList       传入修改的规格
     * @param existModelList 数据库已有的
     * @param existTotalList 数据库已有的
     * @param goods          goodsId、goodsSn
     * @return 使用的和需删除的规格列表
     */
    public EditGoodsModelDTO editGoodsModel(List<EditModelReq> editList, List<GoodsModel> existModelList, List<GoodsModelTotal> existTotalList, Goods goods) {
        // goodsModelSn 后缀数字 的最大值
        int maxNumber = 0;
        int size = Math.max(8, existModelList.size() * 4 / 3 + 1);
        // 处理后使用的列表
        List<GoodsModel> modelList = new ArrayList<>(size);
        List<GoodsModelTotal> totalList = new ArrayList<>(size);
        // modelId: model
        Map<String, GoodsModel> modelIdMap = new HashMap<>(size);
        // modelName: model
        Map<String, GoodsModel> modelNameMap = new HashMap<>(size);
        for (GoodsModel model : existModelList) {
            maxNumber = Math.max(maxNumber, fetchModelSnNum(model.getGoodsModelSn()));
            modelIdMap.put(model.getId(), model);
            modelNameMap.put(model.getModelName(), model);
        }
        // 处理后 使用的规格  modelName+typeName: GoodsModelTotal
        Map<String, GoodsModelTotal> totalMap = new HashMap<>(size);
        // id: GoodsModelTotal
        Map<String, GoodsModelTotal> totalIdMap = new HashMap<>(size);
        for (GoodsModelTotal total : existTotalList) {
            totalMap.put(total.getSubModelName() + total.getModelName(), total);
            totalIdMap.put(total.getId(), total);
        }
        // goodsModelSn 的后缀从已有最大值后设置
        final int[] number = {maxNumber + 1};
        // 当前需保存的规格
        editList.forEach(edit -> {
            // 规格类型处理
            List<String> typeNameList = StrUtil.split(edit.getTypeName(), StrUtil.C_COMMA, true, true);
            List<String> modelNameList = StrUtil.split(edit.getModelName(), StrUtil.C_COMMA, true, true);
            if (typeNameList.isEmpty() || typeNameList.size() != modelNameList.size()) {
                throw new ErrorDataException("规格类型名称及规格名称有误");
            }
            String[] modelNumArray = new String[typeNameList.size()];
            // 规格名称: 类型 用于规格名称排序
            Map<String, ModelAttrNameEnum> modeNameMap = new HashMap<>(Math.max(8, typeNameList.size() * 4 / 3 + 1));
            GoodsModel exist = StrUtil.isEmpty(edit.getModelId()) ? null : modelIdMap.get(edit.getModelId());
            GoodsModel editModel = edit.transTo();
            editModel.setGoodsId(goods.getId());
            // 未传入modelId时可根据规格名称判断是否已存在
            if (null == exist && null != (exist = modelNameMap.get(edit.getModelName()))) {
                editModel.setId(exist.getId());
                modelNameMap.remove(edit.getModelName());
            }
            if (null == exist) {
                editModel.setId(null);
                // 规格编号设置 goodsModelSn
                editModel.setGoodsModelSn(GoodsTrans.genGoodsModelSn(goods.getGoodsSn(), number[0]));
                number[0]++;
            } else {
                editModel.setGoodsModelSn(exist.getGoodsModelSn());
                modelIdMap.remove(exist.getId());
            }
            GoodsTrans.modelInitDefault(editModel);
            // 规格类型处理
            for (int i = 0, len = typeNameList.size(); i < len; i++) {
                // 必须是定义的属性名枚举中的规格类型
                String typeName = typeNameList.get(i);
                String modelName = modelNameList.get(i);
                ModelAttrNameEnum type = ModelAttrNameEnum.getByDesc(typeName);
                if (null == type) {
                    throw new ErrorDataException("商品规格的规格类型有误");
                }
                String key = modelName + typeName;
                GoodsModelTotal modelTotal = totalMap.get(key);
                // sub_model_id 从30开始
                String subNum = String.valueOf(totalList.size() + 30);
                // 无已存在类型时新增, 已有时从待删除map移除
                if (null == modelTotal) {
                    modelTotal = new GoodsModelTotal();
                    modelTotal.setGoodsId(goods.getId());
                    modelTotal.setModelName(type.getDesc());
                    modelTotal.setModelId(type.getType());
                    modelTotal.setSubModelId(subNum);
                    modelTotal.setSubModelName(modelName);
                    totalMap.put(key, modelTotal);
                    totalList.add(modelTotal);
                } else {
                    // 已有的
                    if (totalIdMap.containsKey(modelTotal.getId())) {
                        modelTotal.setSubModelId(subNum);
                        totalIdMap.remove(modelTotal.getId());
                        totalList.add(modelTotal);
                    } else {
                        subNum = modelTotal.getSubModelId();
                    }
                }
                modelNumArray[i] = subNum;
                modeNameMap.put(modelName, type);
            }
            // 规格名称按类型字典排序
            editModel.setModelName(modelNameList.stream()
                    .sorted(Comparator.comparing(modeNameMap::get))
                    .collect(Collectors.joining(StrUtil.COMMA)));
            editModel.setModel(ArrayUtil.join(modelNumArray, StrUtil.COMMA));
            // 规格价格等处理
            modelList.add(editModel);
        });
        return new EditGoodsModelDTO(modelList, totalList, new ArrayList<>(modelIdMap.values()), new ArrayList<>(totalIdMap.values()));
    }

    /**
     * 根据规格编号获取后缀数字
     *
     * @param goodsModelSn
     * @return
     */
    private int fetchModelSnNum(String goodsModelSn) {
        String num = StrUtil.subAfter(goodsModelSn, IGoodsConstant.GOODS_MODEL_INFIX, true);
        try {
            return NumberUtil.parseInt(num);
        } catch (Exception e) {
            return 0;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
            @CacheEvict(value = ScmCacheNameConstant.WECHAT_BUYER_GOODS_PAGE, allEntries = true),
            @CacheEvict(value = ScmCacheNameConstant.GOODS_INFO_DETAIL, allEntries = true)
    })
    public boolean deleteGoodsById(String goodsId) {
        goodsService.removeById(goodsId);
        // 规格删除
        goodsModelService.remove(Wrappers.<GoodsModel>query().lambda()
                .eq(GoodsModel::getGoodsId, goodsId)
        );
        // 规格类型
        goodsModelTotalService.remove(Wrappers.<GoodsModelTotal>query().lambda()
                .eq(GoodsModelTotal::getGoodsId, goodsId)
        );
        // 定价
        goodsPriceRuleService.remove(Wrappers.<GoodsPriceRule>query().lambda()
                .eq(GoodsPriceRule::getGoodsId, goodsId)
        );
        //   平台定价, 商品收藏 删除  供应商品关联
        platformGoodsPriceService.remove(Wrappers.<PlatformGoodsPrice>query().lambda()
                .eq(PlatformGoodsPrice::getGoodsId, goodsId)
        );
        goodsCollectionsService.remove(Wrappers.<GoodsCollections>query().lambda()
                .eq(GoodsCollections::getGoodsId, goodsId)
        );
        scmGoodsUtils.deleteSupplyRelation(goodsId);
        //  todo 赠品 商品售卖规则 商品服务等 启用后需删除
        return true;
    }


    /**
     * 按平台店铺分类id 获取商品对应店铺的商品分类id
     * 分类按名称匹配，找不到时新增分类及父级
     *
     * @param categoryId 平台商品分类
     * @param pmId       平台商家
     * @param shopId     商品所属店铺
     * @param merchantId 商品所属店铺商家
     * @return 商品店铺的分类
     */
    public String specialCategoryFetch(String categoryId, String pmId, String shopId, String merchantId) {
        // 商品分类处理
        GoodsCategory platformCategory = goodsCategoryService.getById(categoryId);
        if (null == platformCategory || !StrUtil.equals(platformCategory.getMerchantId(), pmId)) {
            throw new ErrorDataException("商品分类有误: 需选择平台店铺商品分类");
        }
        // 按名称匹配
        GoodsCategory category = goodsCategoryService.fetchByName(shopId, platformCategory.getName());
        if (null != category) {
            return category.getId();
        }
        // 所需商品的分类
        GoodsCategoryDTO categoryDTO = copyPlatformCategory(platformCategory, shopId, merchantId);
        // 找不到时 查询平台分类所有父级
        Map<String, GoodsCategory> parentMap = goodsCategoryService.fetchParentList(categoryId).stream()
                .collect(Collectors.toMap(GoodsCategory::getId, Function.identity(), (oldValue, value) -> value));
        // 匹配所有平台分类父级到商品店铺
        // 循环处理父级
        GoodsCategoryDTO current = categoryDTO;
        GoodsCategoryDTO parent;
        boolean flag = true;
        while (flag) {
            // 平台父级
            GoodsCategory platformParent = parentMap.get(current.getParentId());
            if (null == platformParent) {
                break;
            }
            // 按名称匹配
            GoodsCategory findParent = goodsCategoryService.fetchByName(shopId, platformParent.getName());
            if (null == findParent) {
                // 循环查找父级
                parent = copyPlatformCategory(platformParent, shopId, merchantId);
                current.setParentCategory(parent);
                current = parent;
            } else {
                parent = new GoodsCategoryDTO(findParent);
                current.setParentCategory(parent);
                flag = false;
            }
        }
        // 保存
        saveCategoryFirstParent(categoryDTO);
        return categoryDTO.getId();
    }

    private GoodsCategoryDTO copyPlatformCategory(GoodsCategory platformCategory, String shopId, String merchantId) {
        GoodsCategoryDTO dto = new GoodsCategoryDTO(platformCategory);
        dto.setId(null);
        dto.setShopId(shopId);
        dto.setMerchantId(merchantId);
        dto.setParentIds(null);
        return dto;
    }

    /**
     * 优先保存父级分类 (递归)
     * 存在id时结束递归
     *
     * @param category parentCategory判断结束
     */
    public void saveCategoryFirstParent(GoodsCategoryDTO category) {
        // 已保存分类不再保存
        if (null == category || StrUtil.isNotBlank(category.getId())) {
            return;
        }
        // 先保存父级分类
        if (null != category.getParentCategory()) {
            saveCategoryFirstParent(category.getParentCategory());
        }
        // id 回传,parent使用
        GoodsCategory goodsCategory = category.transTo();
        goodsCategoryService.saveCategory(goodsCategory);
        category.setId(goodsCategory.getId());
    }


    /**
     * 修改 商品分类和平台商品分类的对应关系
     *
     * @param categoryId
     * @param platformCategoryId
     */
    public void updateSpecialCategory(String categoryId, String platformCategoryId) {
        GoodsCategory update = new GoodsCategory();
        update.setId(categoryId);
        JSONObject json = JSONUtil.createObj();
        json.put("categoryId", platformCategoryId);
        update.setRemarks(json.toString());
        goodsCategoryService.updateById(update);
    }

    // 验证使用

    /**
     * 商品价格验证
     *
     * @param goodsId
     * @return
     */
    public GoodsPriceRule checkedPriceRule(String goodsId) {
        GoodsPriceRule priceRule = goodsPriceRuleService.fetchByGoodsId(goodsId);
        if (null == priceRule) {
            throw new ErrorDataException("商品的价格属性有误");
        }
        return priceRule;
    }

    /**
     * 商品规格类型验证
     *
     * @param goodsId
     * @return
     */
    public List<GoodsModelTotal> checkedGoodsModelTotal(String goodsId) {
        List<GoodsModelTotal> list = goodsModelTotalService.fetchTotalList(goodsId);
        if (list.isEmpty()) {
            throw new ErrorDataException("商品的规格类型列表有误");
        }
        return list;
    }

    /**
     * 商品规格验证
     *
     * @param goodsId
     * @return
     */
    public List<GoodsModel> checkedGoodsModel(String goodsId) {
        List<GoodsModel> list = goodsModelService.fetchModelList(goodsId);
        if (list.isEmpty()) {
            throw new ErrorDataException("商品的规格列表有误");
        }
        return list;
    }

}
